package com.admin.service.sample.impl;

import com.admin.common.context.SampleContext;
import com.admin.common.enums.DeclareScoreStatusEnum;
import com.admin.common.enums.sample.SampleTypeEnum;
import com.admin.common.exception.BizException;
import com.admin.common.util.DateUtils;
import com.admin.common.util.RandomUtil;
import com.admin.domain.Declare;
import com.admin.mapper.DeclareMapper;
import com.admin.service.sample.SampleService;
import com.admin.vo.sample.SampleResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>市抽样</p>
 *
 * @author : weiyang
 * @date : 2022-06-06 10:29
 **/
@Service
@Slf4j
public class CitySampleServiceImpl implements SampleService {

    @Autowired
    private DeclareMapper declareMapper;

    @Override
    public SampleTypeEnum getType() {
        return SampleTypeEnum.CITY_SAMPLE;
    }

    @Override
    public SampleResponse sample(SampleContext sampleContext) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("startTime", DateUtils.dateFormatStr(sampleContext.getStartTime()));
        params.put("endTime", DateUtils.dateFormatStr(sampleContext.getEndTime()));
        params.put("declareType", sampleContext.getDeclareType());
        params.put("scoreStatus", DeclareScoreStatusEnum.PROVINCE_WAIT.getKey());
        params.put("isSubmitProvince", 1);
        params.put("provinceIds", sampleContext.getProvinceIdList());

        //所有待省级评分的样本总数
        List<Declare> declareList = declareMapper.selectSimpleByMap(params);
        if (CollectionUtils.isEmpty(declareList)) {
            throw new BizException(-1, "暂无可抽样的数据");
        }

        AtomicInteger sampleQuantity = new AtomicInteger();
        AtomicInteger areaQuantity = new AtomicInteger();
        List<Integer> sampleIdList = new ArrayList<>();

        Map<Integer, Declare> idMap = declareList.stream().collect(Collectors.toMap(Declare::getId, Function.identity(),  (k1,k2) -> k1));
        Map<Integer, List<Declare>> cityGroupMap = declareList.stream().collect(Collectors.groupingBy(Declare::getCityId));

        cityGroupMap.forEach((k, v) -> {
            //每个市的样本总数
            Integer totalNum = v.size();
            //每个市需要抽样的数量
            int needSampleNum = (int) Math.ceil(totalNum * sampleContext.getSampleRate() / 100d);
            //生成抽样随机数（这里为数组下标）
            List<Integer> numberList = RandomUtil.getRandomList(v.size(), needSampleNum);
            //样本结果
            List<Integer> idList = numberList.stream().map(index -> {
                return v.get(index);
            }).map(Declare::getId).collect(Collectors.toList());

            //计算样本数据中区县的数量
            Set<Integer> areaSampleSet = idList.stream().map(t -> idMap.get(t)).map(Declare::getAreaId).collect(Collectors.toSet());

            sampleQuantity.addAndGet(needSampleNum);
            areaQuantity.addAndGet(areaSampleSet.size());
            sampleIdList.addAll(idList);
        });

        SampleResponse sampleResponse = new SampleResponse();
        sampleResponse.setIdList(sampleIdList);
        sampleResponse.setSampleQuantity(sampleQuantity.get());
        sampleResponse.setCityQuantity(cityGroupMap.size());
        sampleResponse.setAreaQuantity(areaQuantity.get());

        return sampleResponse;
    }
}
